#include "mainwindow.h"
#include "ui_mainwindow.h"

//定时器
//每1000ms定时检测串口状态
void MainWindow::Check_Port_Status_Each_Time()
{
    QStringList PortStrList;
    PortStrList.clear();
    int icnt;
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
         PortStrList += info.portName()+":"+info.description();
    }
    PortStrList.sort();
    for(icnt=0;icnt<PortStrList.size();icnt++)
    {
        if(!portStringList.contains(PortStrList.at(icnt)))
        {
            break;
        }
    }
    if(icnt != PortStrList.size() || PortStrList.size() != portStringList.size())
    {
        portStringList = PortStrList;
        ui->cbx_port->clear();
        ui->cbx_port->addItems(portStringList);
        ui->cbx_port_bat_f210->clear();
        ui->cbx_port_bat_f210->addItems(portStringList);
        ui->cbx_port_disp_f210->clear();
        ui->cbx_port_disp_f210->addItems(portStringList);
        ui->cbx_port_dlbox->clear();
        ui->cbx_port_dlbox->addItems(portStringList);
        ui->cbx_port_f316->clear();
        ui->cbx_port_f316->addItems(portStringList);
        ui->cbx_port_dl8000->clear();
        ui->cbx_port_dl8000->addItems(portStringList);

        if(!Check_current_port(CPortName, ConnectStu, ui->cbx_port))
        {
            LangureStr_Init_Disconnected();
            InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            on_btn_link_clicked();
        }
        if(!Check_current_port(CPortName_disp_f210, ConnectStu_disp_f210, ui->cbx_port_disp_f210))
        {
            LangureStr_Init_Disconnected();
            InsertText(ui->te_prin_disp_f210, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            on_btn_link_disp_f210_clicked();
        }
        if(!Check_current_port(CPortName_dlbox, ConnectStu_dlbox, ui->cbx_port_dlbox))
        {
            on_btn_link_dlbox_clicked();
        }
        if(!Check_current_port(CPortName_f316, ConnStu_f316, ui->cbx_port_f316))
        {
            on_btn_unlink_f316_clicked();
        }
        if(!Check_current_port(CPortName_dl8000, ConnStu_dl8000, ui->cbx_port_dl8000))
        {
            LangureStr_Init_Disconnected();
            InsertText(ui->te_prin_dl8000, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            on_btn_link_dl8000_clicked();
        }
        // f210
        Check_new_device_detected(portStringList, PortList_f210, "CH340", ConnectStu, ui->te_prin);
        Check_new_device_detected(portStringList, PortList_disp_f210, "CH340", ConnectStu_disp_f210, ui->te_prin_disp_f210);
        // dl400
        Check_new_device_detected(portStringList, PortList_dlbox, "Prolific", ConnectStu_dlbox, ui->te_prin_dlbox);
        // f316
        Check_new_device_detected(portStringList, PortList_f316, "CH340", ConnStu_f316, ui->te_prin_f316);
        // dl8000
        Check_new_device_detected(portStringList, PortList_dl8000, "CH340", ConnStu_dl8000, ui->te_prin_dl8000);
    }
	CBX_Port_SizeHint_Set(ui->cbx_port);
    CBX_Port_SizeHint_Set(ui->cbx_port_dlbox);
    CBX_Port_SizeHint_Set(ui->cbx_port_f316);
    CBX_Port_SizeHint_Set(ui->cbx_port_dl8000);
}
void MainWindow::CBX_Port_SizeHint_Set(QComboBox* cbx_port)
{
    QStandardItemModel* model = qobject_cast<QStandardItemModel*>(cbx_port->model());
    for(int icnt=0; icnt<model->rowCount(); ++icnt)
    {
        QStandardItem * item = model->item(icnt);
        item->setSizeHint({ 0, 25 });
    }
}

//每3000ms定时发送同步命令
void MainWindow::Port_F210_Sync_Timer()
{
    QByteArray LineStr;
    LineStr.clear();
    pc_to_mcu_send_data(LineStr, SEND_DATA_SYNC);
    if(RecvStu)
    {
        TimeOutCnt++;
        SyncTimer->start(1000);
        if(9 == TimeOutCnt)
        {
            TimeOutCnt = 0;
            LangureStr_Init_TimeOut(ui->te_prin);
            LangureStr_Init_TimeOut(ui->te_prin_bat);
            // 断开按钮
            LangureStr_Init_Btn_Unlink(ui->btn_link);
            LangureStr_Init_Btn_Unlink(ui->btn_link_bat);
            on_btn_link_clicked();
        }
    }
    else
    {
        RecvStu = true;
        if(0 != TimeOutCnt)
            SyncTimer->start(TIMER_SYNC_TIME_OUT);
        TimeOutCnt = 0;
    }
}

//每次操作的单次计时器
void MainWindow::Port_F210_Once_Timer()
{
    PortStu = PORT_STU_TIMEOUT;
}

//在60s/120s内循环发送读盖板码指令等待 mcu 应答
bool MainWindow::Wait_TimeOut_to_Wait_Mcu_Answer()
{
    RecvStr.clear();
    LastPortStu = PORT_STU_WAIT_OK;
    int icnt=0;
//    if(PORT_STU_ERROR != PortStu || PORT_STU_NULL != PortStu)
//    {
        PortStu = PORT_STU_WAIT;
//    }
    while(PORT_STU_WAIT == PortStu)
    {
        WaitTimer->start(1000);
        while(PORT_STU_WAIT == PortStu) QApplication::processEvents();
        if(WaitTimer->isActive())
        {
            WaitTimer->stop();
        }
        icnt++;
        if(PORT_STU_NULL == PortStu || PORT_STU_ERROR == PortStu || (Model_12 <= ModelStu && icnt > 120) || (Model_12 > ModelStu && icnt > 60))
        {
            return false;
        }
        if(PORT_STU_WAIT_OK == PortStu)
        {
            QByteArray LineStr;
            LineStr.clear();
            pc_to_mcu_send_data(LineStr, SEND_DATA_SYNC);
            return true;
        }
        else
        {
            PortStu = PORT_STU_WAIT;
        }
    }

    return true;
}
//等待 同步 N ms 内mcu应答
void MainWindow::Wait_TimeOut_to_Mcu_Answer(int WaitStu)
{
    WaitTimer->start(10000);
    while(WaitStu == PortStu) QApplication::processEvents();
    WaitTimer->stop();
}
//发送命令超时
bool MainWindow::Wait_TimeOut_to_Send_Three_Time(QByteArray SendBuff, int LastStu, int SendStu)
{
    do
    {
        pc_to_mcu_send_data(SendBuff, SendStu);

        LastPortStu = LastStu;
        PortStu = PORT_STU_WAIT;
        Wait_TimeOut_to_Mcu_Answer(PORT_STU_WAIT);
        if(PORT_STU_TIMEOUT == PortStu)
        {
            RecvData.clear();
            SendOutCnt++;
            if(PageCnt)
            {
                PageCnt--;
            }
        }
        else if(LastPortStu == PortStu)
        {
            SendOutCnt = 0;
        }
        if(SendOutCnt == 10 || PORT_STU_ERROR == PortStu)
        {
            SendOutCnt = 0;
            return false;
        }
    }while(SendOutCnt);

    return true;
}
//等待 N ms 用来等待mcu超时
void MainWindow::Wait_Time_to_Wait_Mcu(int TimeVal)
{
    QElapsedTimer WaitTime;
    WaitTime.start();
    while(!WaitTime.hasExpired(TimeVal))QApplication::processEvents();
    RecvStr.clear();
}

//每3000ms定时发送同步命令
void MainWindow::Port_f316_Sync_Timer()
{
    QByteArray LineStr;
    LineStr.clear();
    Port_f316_Send_Data(LineStr, SEND_DATA_SYNC);
    if(RecvStu_f316)
    {
        TimeOutCnt_f316++;
        SyncTimer_f316->start(1000);
        if(9 == TimeOutCnt_f316)
        {
            TimeOutCnt_f316 = 0;
            LangureStr_Init_TimeOut(ui->te_prin_f316);
            // 断开按钮
            on_btn_unlink_f316_clicked();
        }
    }
    else
    {
        RecvStu_f316 = true;
        if(0 != TimeOutCnt_f316)
            SyncTimer_f316->start(TIMER_SYNC_TIME_OUT);
        TimeOutCnt_f316 = 0;
    }
}

//每次操作的单次计时器
void MainWindow::Port_f316_Once_Timer()
{
    PortStu_f316 = PORT_STU_TIMEOUT;
}

// dlbox每次操作的单次计时器
void MainWindow::Port_Dlbox_Once_Timer()
{
    RespStu_dlbox = USB_PAGE_OUT;
}

//每3000ms定时发送同步命令
void MainWindow::Port_dl8000_Sync_Timer()
{
    QByteArray LineStr;
    LineStr.clear();
    Port_dl8000_Send_Data(LineStr, SEND_DATA_SYNC);
    if(RecvStu_dl8000)
    {
        TimeOutCnt_dl8000++;
        SyncTimer_dl8000->start(1000);
        if(9 == TimeOutCnt_dl8000)
        {
            TimeOutCnt_dl8000 = 0;
            LangureStr_Init_TimeOut(ui->te_prin_dl8000);
            // 断开按钮
            LangureStr_Init_Btn_Unlink(ui->btn_link_dl8000);
            on_btn_link_dl8000_clicked();
        }
    }
    else
    {
        RecvStu = true;
        if(0 != TimeOutCnt_dl8000)
            SyncTimer_dl8000->start(TIMER_SYNC_TIME_OUT);
        TimeOutCnt_dl8000 = 0;
    }
}

//每次操作的单次计时器
void MainWindow::Port_dl8000_Once_Timer()
{
    PortStu_dl8000 = PORT_STU_TIMEOUT;
}

//在60s/120s内循环发送读盖板码指令等待 mcu 应答
bool MainWindow::Port_dl8000_Wait_Answer()
{
    RecvStr_dl8000.clear();
    LastPortStu_dl8000 = PORT_STU_WAIT_OK;
    int icnt = 0;
	PortStu_dl8000 = PORT_STU_WAIT;
    while(PORT_STU_WAIT == PortStu_dl8000)
    {
        WaitTimer_dl8000->start(1000);
        while(PORT_STU_WAIT == PortStu_dl8000) QApplication::processEvents();
        if(WaitTimer_dl8000->isActive())
        {
            WaitTimer_dl8000->stop();
        }
        icnt++;
        if(PORT_STU_NULL == PortStu_dl8000 || PORT_STU_ERROR == PortStu_dl8000 || (Model_12 <= ModelStu_dl8000 && icnt > 120) || (Model_12 > ModelStu_dl8000 && icnt > 60))
        {
            return false;
        }
        if(PORT_STU_WAIT_OK == PortStu_dl8000)
        {
            QByteArray LineStr;
            LineStr.clear();
            Port_dl8000_Send_Data(LineStr, SEND_DATA_SYNC);
            return true;
        }
        else
        {
            PortStu_dl8000 = PORT_STU_WAIT;
        }
    }

    return true;
}
//等待 同步 N ms 内mcu应答
void MainWindow::Port_dl8000_Wait_Stu(int WaitStu)
{
    WaitTimer_dl8000->start(TIMER_SYNC_TIME_OUT*10);
    while(WaitStu == PortStu_dl8000) QApplication::processEvents();
    WaitTimer_dl8000->stop();
}
//发送命令超时
bool MainWindow::Port_dl8000_Send_3Time(QByteArray SendBuff, int LastStu, int SendStu)
{
    do
    {
        Port_dl8000_Send_Data(SendBuff, SendStu);

        LastPortStu_dl8000 = LastStu;
        PortStu_dl8000 = PORT_STU_WAIT;
        Port_dl8000_Wait_Stu(PORT_STU_WAIT);
        if(PORT_STU_TIMEOUT == PortStu_dl8000)
        {
            RecvData.clear();
            SendOutCnt_dl8000++;
            if(PageCnt_dl8000)
            {
                PageCnt_dl8000--;
            }
        }
        else if(LastPortStu_dl8000 == PortStu_dl8000)
        {
            SendOutCnt_dl8000 = 0;
        }
        if(SendOutCnt_dl8000 == 10 || PORT_STU_ERROR == PortStu_dl8000)
        {
            SendOutCnt_dl8000 = 0;
            return false;
        }
    }while(SendOutCnt_dl8000);

    return true;
}
//等待 N ms 用来等待mcu超时
void MainWindow::Port_dl8000_Wait_Time(int TimeVal)
{
    QElapsedTimer WaitTime;
    WaitTime.start();
    while(!WaitTime.hasExpired(TimeVal))QApplication::processEvents();
    RecvStr.clear();
}


